// interface是一种定义结构的方式，主要作用是为：类、对象、函数等规定一种契约，这样可以确保代码的一致性和类型安全，
// 但是要注意interface只能定义格式，不能包含任何实现！

// 一、定义类的结构
// 用interface关键字定义类格式
interface PersonInterface {
    name: string
    age: number
    speak(n: number): void
}

// 用关键字implements去实现PersonInterface接口，格式： classs aaa implements aaaInterface
class IPerson implements PersonInterface {
    // 定义类的时候需要用implements关键字
    constructor(
        public name: string,
        public age: number
    ) { }
    speak(n: number): void {
        for (let i = 0; i < n; i++) {
            console.log(`我是${this.name},我今年${this.age}岁了！`);
        }
    }
}

const iperson = new IPerson('夜南', 26)
iperson.speak(4)

// 二、定义对象的结构
interface UserInfoInterface {
    name: string,
    readonly gender: string   //只读属性
    age?: number     //可选属性
    run: (n: number) => void
}

// 对象去实现UserInfoInterface类型时，不需要加implements关键字，但是变量名和接口名中间有"："  格式为 aaa:aaaInterface
const iuserinfo: UserInfoInterface = {
    // 这里的UserInfoInterface相当于是当类型用了，比如 const aaa :number = 111
    // 而UserInfoInterface相当于变成了type自定义的类型了
    name: '夜南漫剪',
    gender: '男',
    age: 18,
    run(n) {
        console.log(`夜南漫剪第${n}次学习typescript`);
    }
}



// 三、定义函数的结构
interface CountInterface {
    (a: number, b: number): number
}

const icount: CountInterface = (x, y) => {
    // 这里的CountInterface相当于是当类型用了
    // 而CountInterface相当于变成了type自定义的类型了
    return x + y
}

//四、接口之间的继承
interface TeacherInterface {
    name: string,
    age: number
}
interface StudentInterface extends TeacherInterface {
    grade: string
}

const stu: StudentInterface={
    name: 'Dear、夜溪',
    age: 18,
    grade: '四年级'
}

// 五、接口的可合并性(重复性)
interface TestInterface {
    name: string,
    age: number
}
interface TestInterface {
    grade: string
    // name:number  //报错，因为上面限制了name为字符串类型，所以新创建的TestInterface接口里的数据项类型必须与上面保持一致
}
// 当两个接口名重复时，不会像JS那样进行覆盖，而是会合并

const mytestoner: TestInterface = {
    name: '张三',
    age: 18,
    grade: '一年级'
}

// 总结：何时使用接口
// 1、定义对象的格式：描述数据模型、API相应格式、配置对象....等等，是开发中用的最多的场景
// 2、类的契约:规定一个类需要实现哪些属性和方法
// 3、自动合并:一般用于扩展第三方库的类型,这种特性在大型项目中可能会用到